<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
    <title>Javascript 的变量、作用域和内存 | liuz2&#39;s Blog</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1">
    <meta name="generator" content="Hugo 0.63.1" />
    
    
      <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
    

    
    
      <link href="/dist/css/app.9576afd3b3c158d98f48ec5df01fec6a.css" rel="stylesheet">
    

    

    
      

    

    

    <meta property="og:title" content="Javascript 的变量、作用域和内存" />
<meta property="og:description" content="深入了解 JavaScript 中变量的类型、作用域和内存的使用注意事项" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://liuz2.gitee.io/posts/javascript-variables/" />
<meta property="article:published_time" content="2021-10-05T14:49:20+08:00" />
<meta property="article:modified_time" content="2021-10-05T14:49:20+08:00" />
<meta itemprop="name" content="Javascript 的变量、作用域和内存">
<meta itemprop="description" content="深入了解 JavaScript 中变量的类型、作用域和内存的使用注意事项">
<meta itemprop="datePublished" content="2021-10-05T14:49:20&#43;08:00" />
<meta itemprop="dateModified" content="2021-10-05T14:49:20&#43;08:00" />
<meta itemprop="wordCount" content="191">



<meta itemprop="keywords" content="javascript," /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Javascript 的变量、作用域和内存"/>
<meta name="twitter:description" content="深入了解 JavaScript 中变量的类型、作用域和内存的使用注意事项"/>

	
  </head>

  <body class="ma0 avenir bg-white">

    
   
  

  <header>
    <div class="bg-black">
      <nav class="pv3 ph3 ph4-ns" role="navigation">
  <div class="flex-l justify-between items-center center">
    <a href="/" class="f3 fw2 hover-white no-underline white-90 dib">
      
        liuz2&#39;s Blog
      
    </a>
    <div class="flex-l items-center">
      

      
        <ul class="pl0 mr3">
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/about/" title="About page">
              About
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/links/" title="Links page">
              Links
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/timeline/" title="Timeline page">
              Timeline
            </a>
          </li>
          
        </ul>
      
      















    </div>
  </div>
</nav>

    </div>
  </header>



    <main class="pb7" role="main">
      
  
  <article class="flex-l flex-wrap justify-between mw8 center ph3">
    <header class="mt4 w-100">
      <h1 class="f3 athelas mt3 mb1">Javascript 的变量、作用域和内存</h1>
      
      
      <time class="f6 mv1 dib tracked" datetime="2021-10-05T14:49:20&#43;08:00">October 5, 2021</time>

      
      
    </header>
    <div class="nested-copy-line-height lh-copy sans-serif f5 nested-links nested-img mid-gray pr4-l w-two-thirds-l"><h2 id="变量">变量</h2>
<p>JavaScript 的变量分为基本类型（<strong>primitive</strong>）和引用类型。基本类型指简单数据，引用类型指多个值组成的对象。</p>
<p>常见的基本类型有：<code>string</code>, <code>number</code>, <code>bigint</code>, <code>boolean</code>, <code>undefined</code>, <code>symbol</code> 和 <code>null</code>。所有的基本类型是不可变的（<strong>immutable</strong>）。</p>
<p>基本类型在内存中占据固定大小的空间，因此被保存在<strong>栈内存</strong>中。引用类型的值是对象，保存在<strong>堆内存</strong>中。</p>
<p>不能给基本类型的值增加属性，虽然不会报错，只是不会产生任何效果：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">let</span> <span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;Nicholas&#39;</span>;
<span style="color:#a6e22e">name</span>.<span style="color:#a6e22e">age</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">27</span>;
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#a6e22e">name</span>.<span style="color:#a6e22e">age</span>);
<span style="color:#75715e">// =&gt; undefined
</span></code></pre></div><p>JS 中的所有函数传参都是<strong>按值传递</strong>。</p>
<h3 id="bigint">BigInt</h3>
<p>通过在数字增加后缀 <code>n</code>，就得到了 <code>bigint</code> 类型。它可以表示任意精度的整数值，甚至可以超越 <code>Number.MAX_SAFE_INTEGER</code>，进行四则运算。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">typeof</span> <span style="color:#ae81ff">2</span><span style="color:#a6e22e">n</span>;
<span style="color:#75715e">// =&gt; bigint
</span><span style="color:#75715e"></span>
Number.<span style="color:#a6e22e">MAX_SAFE_INTEGER</span>;
<span style="color:#75715e">// =&gt; 9007199254740991
</span><span style="color:#75715e"></span>
Number.<span style="color:#a6e22e">MAX_SAFE_INTEGER</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">2</span>;
<span style="color:#75715e">// =&gt; 9007199254740992 此时通过 number 运算，结果已不再精确
</span><span style="color:#75715e"></span>
<span style="color:#ae81ff">9007199254740993</span>;
<span style="color:#75715e">// =&gt; 9007199254740992 这超出了 JS 的理解范围
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">BigInt</span>(Number.<span style="color:#a6e22e">MAX_SAFE_INTEGER</span>) <span style="color:#f92672">+</span> <span style="color:#ae81ff">2</span><span style="color:#a6e22e">n</span>;
<span style="color:#75715e">// =&gt; 9007199254740993n 转换为 bigint，结果依然精确
</span></code></pre></div><h3 id="检测基本类型">检测基本类型</h3>
<p>要<strong>检测基本数据类型</strong>，可以使用 <code>typeof</code> 操作符：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#e6db74">&#39;Hello&#39;</span>);
<span style="color:#75715e">// =&gt; string
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#66d9ef">true</span>);
<span style="color:#75715e">// =&gt; boolean
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#ae81ff">22</span>);
<span style="color:#75715e">// =&gt; number
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#66d9ef">undefined</span>);
<span style="color:#75715e">// =&gt; undefined
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#a6e22e">Symbol</span>());
<span style="color:#75715e">// =&gt; symbol
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#66d9ef">null</span>);
<span style="color:#75715e">// =&gt; object
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#66d9ef">new</span> Object());
<span style="color:#75715e">// =&gt; object
</span><span style="color:#75715e"></span>
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#66d9ef">typeof</span> <span style="color:#66d9ef">function</span> () {});
<span style="color:#75715e">// =&gt; function
</span></code></pre></div><h3 id="检测引用类型">检测引用类型</h3>
<p>但要检测引用类型时，<code>typeof</code> 用途不大。检测引用类型时，通常我们想知道它是不是某个类型的对象，可以用 <code>instanceof</code> 操作符。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">person</span> <span style="color:#f92672">=</span> {};
<span style="color:#a6e22e">person</span> <span style="color:#66d9ef">instanceof</span> Object;
<span style="color:#75715e">// =&gt; true
</span><span style="color:#75715e"></span>
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">colors</span> <span style="color:#f92672">=</span> [];
<span style="color:#a6e22e">colors</span> <span style="color:#66d9ef">instanceof</span> Array;
<span style="color:#75715e">// =&gt; true
</span><span style="color:#75715e"></span>
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">pattern</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">/a/g</span>;
<span style="color:#a6e22e">pattern</span> <span style="color:#66d9ef">instanceof</span> RegExp;
<span style="color:#75715e">// =&gt; true
</span></code></pre></div><h2 id="执行环境和作用域">执行环境和作用域</h2>
<p><strong>执行环境</strong>（execution context）划定了变量或函数的访问权限边界，影响着它们的行为。每个执行环境都有一个<strong>变量对象</strong>（variable object）。变量对象保存着执行环境中定义的所有变量和函数。</p>
<p>最外层的执行环境是全局执行环境，在浏览器中就是 <code>window</code> 变量，在 Node 中就是 <code>global</code> 变量。</p>
<p>每个函数也有自己的执行环境。</p>
<p>当代码在环境中运行时，会创建变量对象的一个<strong>作用域链</strong>（scope chain）。作用域链保证变量和函数的有序访问。</p>
<h2 id="垃圾回收">垃圾回收</h2>
<p>JS 具有自动垃圾回收机制。常用的垃圾回收策略有两种：<strong>标记清除</strong>（mark-and-sweep）和<strong>引用计数</strong>（reference counting）。</p>
<p>标记清除算法非常简单，容易实现，但是有两个要命的缺点：分配速度慢，容易产生碎片。</p>
<p>引用计数无法处理<strong>循环引用</strong>导致的内存泄漏问题。为了避免循环引用，最好在不使用对象时，手工断开其中的联系。这种做法叫做<strong>解除引用</strong>（dereferencing）：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#a6e22e">myObject</span>.<span style="color:#a6e22e">element</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">null</span>;
<span style="color:#a6e22e">element</span>.<span style="color:#a6e22e">someObject</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">null</span>;
</code></pre></div><h2 id="ref">REF</h2>
<ol>
<li>《JavaScript 高级程序设计》（第 3 版），Nicholas C.Zakas 著，第四章：变量、作用域和内存问题。</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">Primitive</a>, MDN</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol">Symbol</a>, MDN</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#bigint_type">BigInt</a>, MDN</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table">操作符优先级表格</a></li>
<li><a href="https://blog.csdn.net/coderising/article/details/119814329">漫画 ｜ 垃圾回收实在是太垃圾了！</a>，码农翻身，CSDN 博客</li>
</ol>
<a href="https://gitee.com/liuz2/liuz2/blob/master/content/posts/javascript-variables.md#tree_comm_title" class="no-underline db b--black pa2 tc bg-black-90" style="color:#eee;">进入留言</a><ul class="pa0">
  
   <li class="list dib">
     <a href="/tags/javascript" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">javascript</a>
   </li>
  
</ul>
<div class="mt6 instapaper_ignoref">
      
      
      </div>
    </div>

    <aside class="w-30-l mt6-l"><div class="bg-light-gray pa3 nested-list-reset nested-copy-line-height nested-links">
    <p class="f5 b mb3">目录</p>
      <nav id="TableOfContents">
  <ul>
    <li><a href="#变量">变量</a>
      <ul>
        <li><a href="#bigint">BigInt</a></li>
        <li><a href="#检测基本类型">检测基本类型</a></li>
        <li><a href="#检测引用类型">检测引用类型</a></li>
      </ul>
    </li>
    <li><a href="#执行环境和作用域">执行环境和作用域</a></li>
    <li><a href="#垃圾回收">垃圾回收</a></li>
    <li><a href="#ref">REF</a></li>
  </ul>
</nav>
  </div>




  <div class="bg-light-gray pa3 nested-list-reset nested-copy-line-height nested-links">
    <p class="f5 b mb3">相关內容</p>
    <ul class="pa0 list">
	   
	     <li  class="mb2">
          <a href="/posts/string-replace-explained/">string.replace() 详解</a>
        </li>
	    
	     <li  class="mb2">
          <a href="/posts/change-event-of-input/">关于文本输入框 change 事件触发时机</a>
        </li>
	    
    </ul>
</div>

</aside>

  </article>

    </main>
    <footer class="bg-black bottom-0 w-100 pa3" role="contentinfo">
  <div class="flex justify-between">
  <a class="f4 fw4 hover-white no-underline white-70 dn dib-ns pv2 ph3" href="https://liuz2.gitee.io/" >
    &copy;  liuz2's Blog 2022 
  </a>
    <div>














</div>
  </div>
</footer>

    

  <script src="/dist/js/app.3fc0f988d21662902933.js"></script>


  </body>
</html>
